package com.hedl.practice.diyJava.genericity;

import com.hedl.practice.diyJava.genericity.definition_genericty.Pair;

public class Study_Genericity_2 {

    public static void main(String[] args) {
        Pair<Integer> p = new Pair<>(123,456);
        //int n = add(new Pair<>(1,2));       //可行
        int n = add(p);     //报错
        System.out.println(n);

        System.out.println("==============================");
        Pair<Number> p1 = new Pair<>(12.3,4.56);
        Pair<Integer> p2 = new Pair<>(123,456);
        setSame(p1,100);
        setSame(p2,200);
        System.out.println(p1.getFirst()+","+p1.getLast());
        System.out.println(p2.getFirst()+","+p2.getLast());


    }

    //解决报错：Pair<? extends Number>p
    //原始：pair<number>p

    /**
     * <? extends Number>的泛型定义称之为上界通配符（Upper Bounds Wildcards），即把泛型类型T的上界限定在Number了。
     *      限制：可读不可写，null除外
     * @param p
     * @return
     */
    static int add(Pair<? extends Number>p){
        Number first = p.getFirst();
        //Integer last = p.getLast();       报错
        Number last = p.getLast();

        //考察set方法,报错
        /**
         * 这就是<? extends Number>通配符的一个重要限制：
         *      方法参数签名setFirst(? extends Number)无法传递任何Number的子类型给setFirst(? extends Number)
         *      唯一的例外是可以给方法参数传入null
         */
        /*p.setFirst(new Integer(first.intValue() + 100));
        p.setLast(new Integer(last.intValue() + 100));*/

        return first.intValue()+last.intValue();
    }

    /**
     * Pair<? super Integer>p
     * 限制：可写不可读，唯一可读的是接收方必须是object类型
     * @param p
     * @param n
     */
    static void setSame(Pair<? super Integer>p,Integer n){
        p.setFirst(n);
        p.setLast(n);
        //Integer x = p.getFirst();
    }
}
